home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C101.ZIP / UUPC11XS.ZIP / UUCICO / DCPFPKT.C < prev    next >
C/C++ Source or Header  |  1992-11-20  |  17KB  |  500 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    Flow control ("f") protocol.                                    */
  3. /*                                                                    */
  4. /*    This protocol relies on flow control of the data stream.  It    */
  5. /*    is meant for working over links that can (almost) be            */
  6. /*    guaranteed to be errorfree, specifically X.25/PAD links.  A     */
  7. /*    sumcheck is carried out over a whole file only.  If a           */
  8. /*    transport fails the receiver can request retransmission(s).     */
  9. /*    This protocol uses a 7-bit datapath only, so it can be used     */
  10. /*    on links that are not 8-bit transparent.                        */
  11. /*                                                                    */
  12. /*    When using this protocol with an X.25 PAD:  Although this       */
  13. /*    protocol uses no control chars except CR, control chars NULL    */
  14. /*    and ^P are used before this protocol is started; since ^P is    */
  15. /*    the default char for accessing PAD X.28 command mode, be        */
  16. /*    sure to disable that access (PAD par 1).  Also make sure        */
  17. /*    both flow control pars (5 and 12) are set.  The CR used in      */
  18. /*    this proto is meant to trigger packet transmission, hence       */
  19. /*    par 3 should be set to 2; a good value for the Idle Timer       */
  20. /*    (par 4) is 10.  All other pars should be set to 0.              */
  21. /*                                                                    */
  22. /*    Normally a calling site will take care of setting the local     */
  23. /*    PAD pars via an X.28 command and those of the remote PAD via    */
  24. /*    an X.29 command, unless the remote site has a special           */
  25. /*    channel assigned for this protocol with the proper par          */
  26. /*    settings.                                                       */
  27. /*                                                                    */
  28. /*    Author:  Piet Beertema, CWI, Amsterdam, Sep 1984                */
  29. /*                                                                    */
  30. /*    Adapted to uupc 3.0 and THINK C 4.0 by Dave Platt, Jul 1991     */
  31. /*--------------------------------------------------------------------*/
  32.  
  33. /*
  34.  *    $Id: DCPFPKT.C 1.5 1992/11/20 12:38:26 ahd Exp $
  35.  *
  36.  *    $Log: DCPFPKT.C $
  37.  * Revision 1.5  1992/11/20  12:38:26  ahd
  38.  * Drop rcsid
  39.  *
  40.  * Revision 1.4  1992/11/19  03:01:13  ahd
  41.  * drop rcsid
  42.  *
  43.  * Revision 1.3  1992/11/19  02:36:29  ahd
  44.  * Revision 1.2  1992/11/15  20:10:47  ahd
  45.  * Clean up modem file support for different protocols
  46.  *
  47.  */
  48.  
  49. /*--------------------------------------------------------------------*/
  50. /*                        System include files                        */
  51. /*--------------------------------------------------------------------*/
  52.  
  53. #include <stdio.h>
  54. #include <time.h>
  55. #include <string.h>
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /*                    UUPC/extended include files                     */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. #include "lib.h"
  62. #include "dcp.h"
  63. #include "dcpfpkt.h"
  64. #include "dcpsys.h"
  65. #include "hostable.h"
  66. #include "security.h"
  67. #include "ssleep.h"
  68. #include "modem.h"
  69. #include "ulib.h"
  70.  
  71. /*--------------------------------------------------------------------*/
  72. /*                              Defines                               */
  73. /*--------------------------------------------------------------------*/
  74.  
  75. #ifndef MAXMSGLEN
  76. #define MAXMSGLEN BUFSIZ
  77. #endif MAXMSGLEN
  78.  
  79. currentfile();
  80.  
  81. /*--------------------------------------------------------------------*/
  82. /*                    Internal function prototypes                    */
  83. /*--------------------------------------------------------------------*/
  84.  
  85. static int fsendresp(int state);
  86.  
  87. /*--------------------------------------------------------------------*/
  88. /*                          Global variables                          */
  89. /*--------------------------------------------------------------------*/
  90.  
  91. static int chksum;
  92.  
  93. /*--------------------------------------------------------------------*/
  94. /*    f o p e n p k                                                   */
  95. /*                                                                    */
  96. /*    Open "f" protocol to other system                               */
  97. /*--------------------------------------------------------------------*/
  98.  
  99. int fopenpk(const boolean master)
  100. {
  101.    flowcontrol(TRUE);
  102.  
  103.    if ( M_fPacketSize > MAXPACK)
  104.       M_fPacketSize = MAXPACK;
  105.  
  106.    pktsize = M_fPacketSize;
  107.    ssleep(2); /* Give peer time to perform corresponding port setup */
  108.    return OK;
  109. } /* fopenpk */
  110.  
  111. /*--------------------------------------------------------------------*/
  112. /*    f c l o s e p k                                                 */
  113. /*                                                                    */
  114. /*    Shutdown "f" procotol with other system                         */
  115. /*--------------------------------------------------------------------*/
  116.  
  117. fclosepk()
  118. {
  119.    flowcontrol(FALSE);
  120.    return OK;
  121. } /* fclosepk */
  122.  
  123. /*--------------------------------------------------------------------*/
  124. /*    f w r m s g                                                     */
  125. /*                                                                    */
  126. /*    Send a control message to remote system with "f" procotol       */
  127. /*--------------------------------------------------------------------*/
  128.  
  129. int fwrmsg(char *str)
  130. {
  131.    char bufr[MAXMSGLEN];
  132.    char *s = bufr;
  133.  
  134.    while (*str)
  135.       *s++ = *str++;
  136.    if (*(s-1) == '\n')
  137.       s--;
  138.    *s++ = '\r';
  139.    if (swrite(bufr, s - bufr) == (s - bufr))
  140.       return OK;
  141.    else
  142.       return FAILED;
  143. } /* fwrmsg */
  144.  
  145. /*--------------------------------------------------------------------*/
  146. /*    f r d m s g                                                     */
  147. /*                                                                    */
  148. /*    Read a control message from remote host with "f" protocol       */
  149. /*--------------------------------------------------------------------*/
  150.  
  151. int frdmsg(char *str)
  152. {
  153.    char *smax;
  154.    char *s = str;
  155.  
  156.    smax = s + MAXPACK - 1;
  157.    for (;;) {
  158.       if (sread(s, 1, M_fPacketTimeout) <= 0)
  159.       {
  160.          printmsg(0,"frdmsg: timeout reading message");
  161.          *s++ = '\0';
  162.          goto msgerr;
  163.       }
  164.       if (*s == '\r')
  165.          break;
  166.       if (*s < ' ')
  167.          continue;
  168.       if (s++ >= smax)
  169.       {
  170.          printmsg(0,"frdmsg: buffer overflow");
  171.          *--s = '\0';
  172.          goto msgerr;
  173.       } /* if (s++ >= smax) */
  174.    }
  175.    *s = '\0';
  176.    return OK;
  177.  
  178. msgerr:
  179.    printmsg(0,"frdmsg: Message received \"%s\"", str);
  180.    return FAILED;
  181. } /* frdmsg */
  182.  
  183. /*--------------------------------------------------------------------*/
  184. /*    f g e t p k t                                                   */
  185. /*                                                                    */
  186. /*    Receive an "f" protocol packet of data from the other system    */
  187. /*--------------------------------------------------------------------*/
  188.  
  189. int fgetpkt(char *packet, int *bytes)
  190. {
  191.    char *op, c, *ip;
  192.    int sum, len, left;
  193.    char buf[5], tbuf[1];
  194.    int i;
  195.    static char special = 0;
  196.    static boolean eof = FALSE;
  197.  
  198. /*--------------------------------------------------------------------*/
  199. /*                    Handle EOF on previous call                     */
  200. /*--------------------------------------------------------------------*/
  201.  
  202.    if ( eof )
  203.    {
  204.       eof = FALSE;
  205.       printmsg(0,"fgetpkt: EOF from other host");
  206.       *bytes = 0;
  207.       if (fsendresp(OK) == OK)
  208.          return OK;
  209.       else
  210.          return FAILED;
  211.    } /* if ( eof ) */
  212.  
  213.    left = pktsize;
  214.    op = packet;
  215.    sum = chksum;
  216.  
  217. /*--------------------------------------------------------------------*/
  218. /*                     Loop to fill up one packet                     */
  219. /*--------------------------------------------------------------------*/
  220.  
  221.    do {
  222.       ip = tbuf;
  223.       len = sread(ip, 1, M_fPacketTimeout); /* single-byte reads for now */
  224.       if (len == 0) {
  225.          printmsg(0,"fgetpkt: Timeout after %d seconds", M_fPacketTimeout);
  226.          return FAILED;               /* Fail if timed out */
  227.       }
  228.       if ((*ip &= 0177) >= '\172') {
  229.          if (special) {
  230.             special = 0;
  231.             if (*ip++ != '\176')
  232.             {
  233.                printmsg(0,"fgetpkt: Did not expect character ^%c (x%02x)",
  234.                   (char) (*(ip-1) + 'A') , (int) *(ip-1));
  235.                goto dcorr;
  236.             }
  237.             len = 0;
  238.  
  239.             while (len < 5) {
  240.                i = sread(&buf[len], 5 - len, M_fPacketTimeout);
  241.                if (i == 0) {
  242.                   printmsg(0,
  243.                      "fgetpkt: Timeout reading %d chars after %d seconds",
  244.                               5 - len, M_fPacketTimeout);
  245.                   goto dcorr;
  246.                }
  247.                len += i;
  248.             }
  249.  
  250.             printmsg(6, "fgetpkt: buf=|%.*s|", len , packet);
  251.             if (buf[4] != '\r')
  252.             {
  253.                printmsg(0,
  254.                   "fgetpkt: error: Expected carriage return, "
  255.                    "not %s%c (x%02x)",
  256.                   (buf[4] < ' ') ? "^" : "" ,
  257.                   (char) (buf[4] + ((buf[4] < ' ') ? 'A' : 0)),
  258.                   (int) buf[4]);
  259.                goto dcorr;
  260.             }
  261.             sscanf(buf, "%4x", &chksum);
  262.             *bytes = op - packet;
  263.             if (chksum == sum) {
  264.                eof = TRUE;
  265.                printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  266.                return OK;
  267.             } else {
  268.                printmsg(0, "fgetpkt: Checksum mismatch, told %04x, calc %04x",
  269.                             chksum, sum);
  270.                fsendresp(RETRY);
  271.                return RETRY;
  272.             }
  273.          }
  274.          special = *ip++;
  275.       } else {
  276.          if (*ip < '\040') {
  277.             printmsg(0,"fgetpkt: error: got control character ^%c (%x)",
  278.                   (char) (*ip + 'A') , (int) *ip);
  279.             goto dcorr;
  280.          }
  281.  
  282.          switch (special) {
  283.             case 0:
  284.                c = (char) (*ip++);
  285.                break;
  286.             case '\172':
  287.                c = (char) (*ip++ - 0100);
  288.                break;
  289.             case '\173':
  290.                c = (char) (*ip++ + 0100);
  291.                break;
  292.             case '\174':
  293.                c = (char) (*ip++ + 0100);
  294.                break;
  295.             case '\175':
  296.                c = (char) (*ip++ + 0200);
  297.                break;
  298.             case '\176':
  299.                c = (char) (*ip++ + 0300);
  300.                break;
  301.             default:
  302.                printmsg(0,"fgetpkt: Invalid special chracter 0x%2x",
  303.                           (int) special );
  304.                panic();
  305.                c = '\0';
  306.          }
  307.  
  308.          *op++ = c;
  309.          left --;
  310.          if (sum & 0x8000) {
  311.             sum <<= 1;
  312.             sum++;
  313.          } else
  314.             sum <<= 1;
  315.          sum += c & 0377;
  316.          sum &= 0xffff;
  317.          special = 0;
  318.       }
  319.    } while (left > 0);
  320.  
  321. /*--------------------------------------------------------------------*/
  322. /*            The packet is full of data, return to caller            */
  323. /*--------------------------------------------------------------------*/
  324.  
  325.    *bytes = pktsize;
  326.    printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  327.    chksum = sum;
  328.    return OK;
  329.  
  330. /*--------------------------------------------------------------------*/
  331. /*            The data is corrupt; flush the incoming file            */
  332. /*--------------------------------------------------------------------*/
  333.  
  334. dcorr:
  335.    printmsg (0, "Data corrupted, skipping to EOF");
  336.  
  337.    len = 1;
  338.    while (len)
  339.       len = sread(packet, 1, M_fPacketTimeout);
  340.  
  341.    fsendresp(RETRY);
  342.    return RETRY;
  343. } /* fgetpkt */
  344.  
  345. /*--------------------------------------------------------------------*/
  346. /*    f s e n d p k t                                                 */
  347. /*                                                                    */
  348. /*    Send an "f" protocol packet to the other system                 */
  349. /*--------------------------------------------------------------------*/
  350.  
  351. fsendpkt(char *ip, int len)
  352. {
  353.    char *op;
  354.    int sum, nl;
  355.    int ret;
  356.    char obuf[MAXPACK * 2];
  357.    op = obuf;
  358.    nl = 0;
  359.    sum = chksum;
  360.    if (len == 0)
  361.    {
  362.       printmsg(0,"fsendpkt: Internal error: zero length for packet");
  363.       return FAILED;
  364.    }
  365.    do {
  366.       if (sum & 0x8000) {
  367.          sum <<= 1;
  368.          sum++;
  369.       } else
  370.          sum <<= 1;
  371.       sum += *ip & 0377;
  372.       sum &= 0xffff;
  373.       if (*ip & 0200) {
  374.          *ip &= 0177;
  375.          if (*ip < 040) {
  376.             *op++ = '\174';
  377.             *op++ = (char) (*ip++ + 0100);
  378.          } else
  379.          if (*ip <= 0171) {
  380.             *op++ = '\175';
  381.             *op++ = *ip++;
  382.          }
  383.          else {
  384.             *op++ = '\176';
  385.             *op++ = (char) (*ip++ - 0100);
  386.          }
  387.          nl += 2;
  388.       } else {
  389.          if (*ip < 040) {
  390.             *op++ = '\172';
  391.             *op++ = (char) (*ip++ + 0100);
  392.             nl += 2;
  393.          } else
  394.          if (*ip <= 0171) {
  395.             *op++ = *ip++;
  396.             nl++;
  397.          } else {
  398.             *op++ = '\173';
  399.             *op++ = (char) (*ip++ - 0100);
  400.             nl += 2;
  401.          }
  402.       }
  403.    } while (--len > 0);
  404.    chksum = sum;
  405.    ret = swrite(obuf, nl);
  406.    if ( ret == nl )
  407.       return OK;
  408.    else
  409.       return FAILED;
  410. } /* fsendpkt */
  411.  
  412. /*--------------------------------------------------------------------*/
  413. /*    f f i l e p k t                                                 */
  414. /*                                                                    */
  415. /*    Prepare for processing an "f" procotol file transfer            */
  416. /*--------------------------------------------------------------------*/
  417.  
  418. int ffilepkt( void)
  419. {
  420.    chksum = 0xffff;
  421.    printmsg(3,"ffilepkt: Checksum reset");
  422.    return OK;
  423. } /* ffilepkt */
  424.  
  425. /*--------------------------------------------------------------------*/
  426. /*    f e o f                                                         */
  427. /*                                                                    */
  428. /*    Transmit "f" protocol end of file to the other system           */
  429. /*--------------------------------------------------------------------*/
  430.  
  431. int feofpkt( void )
  432. {
  433.    char ibuf[MAXMSGLEN];
  434.  
  435. /*--------------------------------------------------------------------*/
  436. /*               Transmit EOF with an attached checksum               */
  437. /*--------------------------------------------------------------------*/
  438.  
  439.    printmsg(0,"feofpkt: sending EOF");
  440.    sprintf(ibuf, "\176\176%04x", chksum);
  441.    printmsg(2,"--> %s", ibuf);
  442.    fwrmsg(ibuf);
  443.  
  444. /*--------------------------------------------------------------------*/
  445. /*                 Now get the response and report it                 */
  446. /*--------------------------------------------------------------------*/
  447.  
  448.    if (frdmsg(ibuf) == FAILED)
  449.       return FAILED;
  450.  
  451.    printmsg(2,"<-- %s",ibuf);
  452.  
  453. /*--------------------------------------------------------------------*/
  454. /*              Determine our next step from the result               */
  455. /*--------------------------------------------------------------------*/
  456.  
  457.    switch(*ibuf)
  458.    {
  459.       case 'R':
  460.          return RETRY;
  461.  
  462.       case 'G':
  463.          return OK;
  464.  
  465.       default:
  466.          return FAILED;
  467.  
  468.    } /* switch */
  469.  
  470. } /* feofpkt */
  471.  
  472. /*--------------------------------------------------------------------*/
  473. /*    f s e n d r e s p                                               */
  474. /*                                                                    */
  475. /*    Send result to a file transfer to other host                    */
  476. /*--------------------------------------------------------------------*/
  477.  
  478. static int fsendresp(int state)
  479. {
  480.    char *s;
  481.    switch (state)
  482.    {
  483.       case OK:
  484.          s = "G";
  485.          break;
  486.  
  487.       case RETRY:
  488.          s = "R";
  489.          break;
  490.  
  491.       default:
  492.          s = "Q";
  493.          break;
  494.    }
  495.  
  496.    printmsg(2,"--> %s", s);
  497.    return fwrmsg(s);
  498.  
  499. } /* fsendresp */
  500.